<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        ul {
            width: 400px;
            height: 400px;
            border: 1px solid #ccc;
        }
    </style>
    <script>
        // **********闭包的问题**********
        // 如果内部函数使用外部函数的变量，在外部函数执行完成之前变量有所改变时，内部函数只能获取最后改变的值，无法获取定义时的值，就会产生闭包
        function add() {
            for (var i = 1; i <= 5; i++) {
                var li = document.createElement('li')
                li.innerText='li'+i;
                li.onclick=function(){  //此函数为一个回调函数当事件发生时执行，此时循环已经结束
                    console.log('点击了第'+i+'个li'); //如果内部函数使用外部函数的变量，在外部函数执行完成之前变量有所改变时，内部函数只能获取最后改变的值，无法获取定义时的值，就会产生闭包
                }
                document.getElementById('myul').appendChild(li);
            }
        }

        // 解决方式1
        // ***不在函数内部定义函数，将函数定义在外面，在函数内部去调用
        function add(){
            for(var i = 1;i<=5;i++){
                var x=creat(i);//定义变量来接收所有li，传入参数i=num
                document.getElementById('myul').appendChild(x)
            }
        }
        function creat(num){ 
            var li = document.createElement('li');
            li.innerText='li'+num;
            li.onclick=function(){
                console.log('点击了第'+num+'个li');
            }
            return li
        }

        // 解决方式2
        // ***为元素附加属性，来储存变量
        function add() {
            for (var i = 1; i <= 5; i++) {
                var li = document.createElement('li')
                li.innerText='li'+i;
                li.x=i  //此时定义的x为属性，并非变量(为每个li都添加了属性x，值为i，当li发生事件时通过this事件源获取到其属性x的值为i)
                li.onclick=function(){  
                    console.log('点击了第'+this.x+'个li'); 
                }
                document.getElementById('myul').appendChild(li);
            }
        }

        // 解决方式3
        // ***使用let来声明变量
        // 块级作用域（在一对花括号（如if语句，for循环中）内声明的变量，只能在该代码块内访问）
        function add() {
            for (let i = 1; i <= 5; i++) {  //let 支持块级作用域 它所声明的变量所在的区域不会受外部影响，称为暂时性死区
                var li = document.createElement('li')
                li.innerText = 'li' + i;
                li.onclick = function () {
                    console.log('点击了第' + i + '个li');
                }
                document.getElementById('myul').appendChild(li);
            }
        }
    </script>
</head>

<body>
    <button onclick="add()">添加元素</button>
    <ul id="myul">

    </ul>
</body>

</html>